/*
 * $Id: ActOnwatchTaskDAO.java,v 1.16 2009/07/10 14:41:10 navdeep_mahajan Exp $
 * 
 * Copyright (C) 2008 General Electric Company. All Rights Reserved.
 * 
 * This software is the confidential and proprietary information of the General
 * Electric Company (GE). You shall not disclose this software and shall use it
 * only in accordance with the terms of the license agreement you entered into
 * with GE.
 * 
 * GE MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
 * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
 * NON-INFRINGEMENT. GE SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
 * AS A RESULT OF USING, MODIFYING, OR DISTRIBUTING THIS SOFTWARE OR ITS
 * DERIVATIVES.
 */
package com.ge.healthcare.autosc.common.database.dao;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;

import com.ge.healthcare.autosc.common.ASCLogger;
import com.ge.healthcare.autosc.common.ASCUtil;
import com.ge.healthcare.autosc.common.database.pojo.ActOnwatchTask;
import com.ge.healthcare.autosc.common.database.pojo.ActTask;
import com.ge.healthcare.autosc.common.database.pojo.CfgCodeDetails;
import com.ge.healthcare.autosc.common.database.pojo.CfgTaskType;

public class ActOnwatchTaskDAO extends BaseDAO implements IOnwatchTaskDAO {

	/**
	 * Eclipse generated
	 */
	private static final long serialVersionUID = -2311196201076996441L;
	private ICodeDetailsDAO codeDetailsDAO = null;
	private ITaskTypeDAO taskTypeDAO = null;
	
	
	private static final Long INITIAL_ONWATCH_TASK_LIST_ID = 0L;
	private static final Long DEFAULT_TASK_ORDER = 0L;
	
	public ActOnwatchTaskDAO() {
		super(ActOnwatchTask.TABLE_NAME);
	}

	/**
	 * @param codeDetailsDAO
	 *            the codeDetailsDAO to set
	 */
	public void setCodeDetailsDAO(ICodeDetailsDAO codeDetailsDAO) {
		this.codeDetailsDAO = codeDetailsDAO;
	}
	
	public Long getNewOnwatchTaskListId() {
		ASCLogger.debug(this.getClass(), "getNewOnwatchTaskListId", "get new onwatch taskList Id");
		return (Long)getHibernateTemplate().execute( new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException {
				return (Long)session.createSQLQuery(
					"select act_onwatch_task_list_id_seq.nextVal as id from dual")
					.addScalar("id", Hibernate.LONG).uniqueResult();
			}
		});
	}
	
	public List<ActOnwatchTask> getByTaskId(Long taskId) {
		List<ActOnwatchTask> actOnwatchTaskLst = new Vector<ActOnwatchTask>();
		List<?> results = findByProperty(ActOnwatchTask.COL_TASK_ID, taskId);
		if (!ASCUtil.isNullOrEmptyList(results)) {
			for (int iCount = 0; iCount < results.size(); iCount++) {
				actOnwatchTaskLst.add((ActOnwatchTask)results.get(iCount));
			}
		}
		return actOnwatchTaskLst;
	}

	public List<ActOnwatchTask> getByTaskListId(Long taskListId) {
		List<ActOnwatchTask> actOnwatchTaskLst = new Vector<ActOnwatchTask>();
		List<?> results = findByProperty(ActOnwatchTask.COL_ONWATCH_TASK_LIST_ID, taskListId);
		if (!ASCUtil.isNullOrEmptyList(results)) {
			for (int iCount = 0; iCount < results.size(); iCount++) {
				actOnwatchTaskLst.add((ActOnwatchTask)results.get(iCount));
			}
		}
		return actOnwatchTaskLst;
	}
	
	public ActOnwatchTask getByOnwatchTaskID(Long onwatchTaskId) {
		Object onwatchTask = findObjectByID(ActOnwatchTask.COL_ONWATCH_TASK_ID, onwatchTaskId);
		if (!ASCUtil.isNullOrEmptyObject(onwatchTask)) {
			return (ActOnwatchTask) onwatchTask;
		}
		return null;
	}
	
	public ActOnwatchTask getOnwatchTaskByTaskAndTaskList(Long taskListId, Long taskId) {
		HashMap<String, Object> queryValues = new HashMap<String, Object>();
		queryValues.put(ActOnwatchTask.COL_ONWATCH_TASK_LIST_ID, taskListId);
		queryValues.put(ActOnwatchTask.COL_TASK_ID, taskId);
		List<?> lstObject = findByProperties(queryValues);
		if (!ASCUtil.isNullOrEmptyList(lstObject)) {
			return (ActOnwatchTask) lstObject.get(0);
		}
		return null;
	}
	
	public List<ActOnwatchTask> markOnwatchTaskBySystemAndStatus(final String systemId, final String codeName, final String status) {
		CfgCodeDetails codeDetails = codeDetailsDAO.getUniqueCodedetailsByCodeName(codeName);
		Vector<ActOnwatchTask> onwatchTaskList = new Vector<ActOnwatchTask>();
		if(codeDetails != null) {
			ArrayList<String> paramNames = new ArrayList<String>();
			paramNames.add("systemId");
			paramNames.add("codeId");
			paramNames.add("status");
			ArrayList<Object> values = new ArrayList<Object>();
			values.add(systemId);
			values.add(codeDetails.getCodeId());
			values.add(status);
			List<?> rs = getHibernateTemplate()
				.findByNamedQueryAndNamedParam("onwatchTasks", paramNames.toArray(new String[3]), values.toArray());
			for(int i=0;i<rs.size();i++) {
				ActOnwatchTask actOnwatchTask = (ActOnwatchTask)rs.get(i);
				onwatchTaskList.add(actOnwatchTask);
			}	
		}
		return onwatchTaskList;
	}
	
	public void releaseOnwatchTaskByTaskListId(Long taskListId) {
		List<ActOnwatchTask> onwatchTasks = this.getByTaskListId(taskListId);
		for(ActOnwatchTask onwatchTask: onwatchTasks) {
			onwatchTask.setStatus(ActOnwatchTask.NEW_STATUS);
			onwatchTask.resetOnwatchTaskListId();
			save(onwatchTask);
		}
	}
	
	
	/**
	 * Saves the initial on watch task to the DB
	 * @param task
	 */
	public void saveInitialOnWatchTask(ActTask task){
		ActOnwatchTask onWatchTask = new ActOnwatchTask();
		onWatchTask.setOnwatchTaskListId(INITIAL_ONWATCH_TASK_LIST_ID);
		onWatchTask.setTaskId(task.getTaskId());
		onWatchTask.setEnteredDate(new Date());
		
		CfgTaskType taskType = taskTypeDAO.getByName(task.getTaskType());
		onWatchTask.setExecutionTimeInSec(taskType.getRuntimeLength());
		onWatchTask.setTaskOrder(DEFAULT_TASK_ORDER);
		onWatchTask.setStatus(ActOnwatchTask.NEW_STATUS);
		this.save(onWatchTask);
	}
	
	/**
	 * Returns all onwatch tasks in the queue
	 * @return
	 */
	public List<ActOnwatchTask> getAllNewTasks() {
		Map<String, Object> whereClause = new HashMap<String, Object>();
		whereClause.put(ActOnwatchTask.COL_STATUS, ActOnwatchTask.NEW_STATUS);
		whereClause.put(ActOnwatchTask.COL_ONWATCH_TASK_LIST_ID, INITIAL_ONWATCH_TASK_LIST_ID);
		List<?> rtvdResults = findByProperties(whereClause);
		if (ASCUtil.isNullOrEmptyList(rtvdResults)){
			return null;
		}
		List<ActOnwatchTask> onWatchTasks = new ArrayList<ActOnwatchTask>();
		for (Object task : rtvdResults){
			onWatchTasks.add((ActOnwatchTask)task);
		}
		return onWatchTasks;
	}
	
	/**
	 * Deletes tasks by task Id
	 * @param taskId
	 */
	public void deleteByTaskId(Long taskId){
		this.deleteByProperty(ActOnwatchTask.COL_TASK_ID, taskId);
	}
	
	
	/**
	 * @see com.ge.healthcare.autosc.common.database.dao.BaseDAO#save(java.lang.Object)
	 */
	public void save(Object pojo) {
		super.save(pojo);
	}

	/**
	 * @see com.ge.healthcare.autosc.common.database.dao.IRequestTypeDAO#saveAlways(java.lang.Object)
	 */
	public void saveAlways(Object pojo) {
		super.save(pojo);
	}

	/**
	 * @see com.ge.healthcare.autosc.common.database.dao.BaseDAO#deleteByID(java.lang.Object)
	 */
	public void deleteByID(Object pojo) {
		super.deleteByID(pojo);
	}

	/**
	 * @see com.ge.healthcare.autosc.common.database.dao.BaseDAO#refresh(java.lang.Object)
	 */
	public void refresh(Object pojo) {
		super.refresh(pojo);
	}

	/**
	 * @param taskTypeDAO the taskTypeDAO to set
	 */
	public void setTaskTypeDAO(ITaskTypeDAO taskTypeDAO) {
		this.taskTypeDAO = taskTypeDAO;
	}
}
